Telegram Group & Telegram Channel
Вопрос: Один из ваших товарищей по команде отправил этот код на проверку. Этот код несет потенциальную угрозу. Определите ее и предложите решение для ее устранения.

package main 

import (
"fmt"
"time"
)

func main () {
ch := make ( chan int )

go func () {
time.Sleep( 2 * time.Second)
ch <- 42
fmt.Println( "Отправлено: 42" )
}()

val := <-ch
fmt.Println( "Получено:" , val)

fmt.Println( "Продолжение выполнения..." )
}


🌟 На первый взгляд ничего подозрительного в этом коде. Если мы попробуем его запустить, он действительно скомпилируется и запустится без каких-либо заметных проблем.

[Running] go run "main.go"

Отправлено: 42
Получено: 42
Продолжение выполнения...

[Done] exited with code=0 in 2.124 seconds


💡 Сам код тоже кажется в порядке. У нас есть правильно реализованное параллельное потребление с двумя горутинами, работающими независимо. Давайте разберем код и посмотрим, что происходит:

🌟 Канал ch создан с помощью make(chan int). Это небуферизованный канал.

🌟 Запускается горутина, которая спит 2 секунды, а затем отправляет значение 42 на канал.

🌟 Основная функция выполняет операцию чтения по ch с помощью val := <-ch.

🔍 Опять же, кажется, все в порядке. Но на самом деле операция отправки задерживается. Анонимная горутина ждет 2 секунды, прежде чем отправить значение в канал. Поэтому, когда мы запускаем этот код, основная функция начинает считывать канал и ожидает там значение, прежде чем канал будет заполнен значением. Эта операция блокирует дальнейшее выполнение кода.

❗️ Подобная блокировка может вызвать серьезные проблемы с параллелизмом. Если основная горутина (или любая критическая горутина) блокируется на неопределенное время, ожидая данные, это может помешать выполнению других важных задач, что приведет к взаимоблокировкам или неотзывчивому поведению.

💡 Чтобы избежать блокирования чтения, можно использовать неблокирующие альтернативы, такие как оператор select с вариантом по умолчанию. Оператор select в Go — это мощная функция, которая позволяет goroutine ожидать несколько операций связи, что позволяет выполнять неблокирующие операции и обрабатывать несколько каналов. Оператор select работает, оценивая несколько операций канала и продолжая с первой готовой. Если несколько операций готовы, одна из них выбирается случайным образом. Если ни одна операция не готова, выполняется вариант по умолчанию, если он есть, что делает его неблокирующей операцией.

🔍 Вот его синтаксис:
select { 
case <-ch1:
// Сделать что-то, когда ch1 готов к приему
case ch2 <- value :
// Сделать что-то, когда ch2 готов к отправке
default :
// Сделать что-то, когда ни один канал не готов (неблокируемый путь)
}


🌟 Теперь исправим изначальную проблему с помощью select:
package main 

import (
"fmt"
"time"
)

func main () {
ch := make ( chan int )

// Goroutine для отправки данных в канал через 2 секунды
go func () {
time.Sleep( 2 * time.Second)
ch <- 42
fmt.Println( "Отправлено: 42" )
}()

// Основная функция, выполняющая неблокирующее чтение
for {
select {
case val := <-ch:
fmt.Println( "Получено:" , val)
fmt.Println( "Продолжение выполнения..." )
return
default :
fmt.Println( "Значения не были получены" )
time.Sleep( 500 * time.Millisecond) // Некоторое время ждем, чтобы предотвратить зацикливание
// обрабатываем поток выполнения инструкций и операций, которые должны быть продолжены
}
}
}



@golang_interview
Please open Telegram to view this post
VIEW IN TELEGRAM



tg-me.com/golangtests/711
Create:
Last Update:

Вопрос: Один из ваших товарищей по команде отправил этот код на проверку. Этот код несет потенциальную угрозу. Определите ее и предложите решение для ее устранения.

package main 

import (
"fmt"
"time"
)

func main () {
ch := make ( chan int )

go func () {
time.Sleep( 2 * time.Second)
ch <- 42
fmt.Println( "Отправлено: 42" )
}()

val := <-ch
fmt.Println( "Получено:" , val)

fmt.Println( "Продолжение выполнения..." )
}


🌟 На первый взгляд ничего подозрительного в этом коде. Если мы попробуем его запустить, он действительно скомпилируется и запустится без каких-либо заметных проблем.

[Running] go run "main.go"

Отправлено: 42
Получено: 42
Продолжение выполнения...

[Done] exited with code=0 in 2.124 seconds


💡 Сам код тоже кажется в порядке. У нас есть правильно реализованное параллельное потребление с двумя горутинами, работающими независимо. Давайте разберем код и посмотрим, что происходит:

🌟 Канал ch создан с помощью make(chan int). Это небуферизованный канал.

🌟 Запускается горутина, которая спит 2 секунды, а затем отправляет значение 42 на канал.

🌟 Основная функция выполняет операцию чтения по ch с помощью val := <-ch.

🔍 Опять же, кажется, все в порядке. Но на самом деле операция отправки задерживается. Анонимная горутина ждет 2 секунды, прежде чем отправить значение в канал. Поэтому, когда мы запускаем этот код, основная функция начинает считывать канал и ожидает там значение, прежде чем канал будет заполнен значением. Эта операция блокирует дальнейшее выполнение кода.

❗️ Подобная блокировка может вызвать серьезные проблемы с параллелизмом. Если основная горутина (или любая критическая горутина) блокируется на неопределенное время, ожидая данные, это может помешать выполнению других важных задач, что приведет к взаимоблокировкам или неотзывчивому поведению.

💡 Чтобы избежать блокирования чтения, можно использовать неблокирующие альтернативы, такие как оператор select с вариантом по умолчанию. Оператор select в Go — это мощная функция, которая позволяет goroutine ожидать несколько операций связи, что позволяет выполнять неблокирующие операции и обрабатывать несколько каналов. Оператор select работает, оценивая несколько операций канала и продолжая с первой готовой. Если несколько операций готовы, одна из них выбирается случайным образом. Если ни одна операция не готова, выполняется вариант по умолчанию, если он есть, что делает его неблокирующей операцией.

🔍 Вот его синтаксис:
select { 
case <-ch1:
// Сделать что-то, когда ch1 готов к приему
case ch2 <- value :
// Сделать что-то, когда ch2 готов к отправке
default :
// Сделать что-то, когда ни один канал не готов (неблокируемый путь)
}


🌟 Теперь исправим изначальную проблему с помощью select:
package main 

import (
"fmt"
"time"
)

func main () {
ch := make ( chan int )

// Goroutine для отправки данных в канал через 2 секунды
go func () {
time.Sleep( 2 * time.Second)
ch <- 42
fmt.Println( "Отправлено: 42" )
}()

// Основная функция, выполняющая неблокирующее чтение
for {
select {
case val := <-ch:
fmt.Println( "Получено:" , val)
fmt.Println( "Продолжение выполнения..." )
return
default :
fmt.Println( "Значения не были получены" )
time.Sleep( 500 * time.Millisecond) // Некоторое время ждем, чтобы предотвратить зацикливание
// обрабатываем поток выполнения инструкций и операций, которые должны быть продолжены
}
}
}



@golang_interview

BY Go tests


Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283

Share with your friend now:
tg-me.com/golangtests/711

View MORE
Open in Telegram


Go tests Telegram | DID YOU KNOW?

Date: |

The SSE was the first modern stock exchange to open in China, with trading commencing in 1990. It has now grown to become the largest stock exchange in Asia and the third-largest in the world by market capitalization, which stood at RMB 50.6 trillion (US$7.8 trillion) as of September 2021. Stocks (both A-shares and B-shares), bonds, funds, and derivatives are traded on the exchange. The SEE has two trading boards, the Main Board and the Science and Technology Innovation Board, the latter more commonly known as the STAR Market. The Main Board mainly hosts large, well-established Chinese companies and lists both A-shares and B-shares.

How to Use Bitcoin?

n the U.S. people generally use Bitcoin as an alternative investment, helping diversify a portfolio apart from stocks and bonds. You can also use Bitcoin to make purchases, but the number of vendors that accept the cryptocurrency is still limited. Big companies that accept Bitcoin include Overstock, AT&T and Twitch. You may also find that some small local retailers or certain websites take Bitcoin, but you’ll have to do some digging. That said, PayPal has announced that it will enable cryptocurrency as a funding source for purchases this year, financing purchases by automatically converting crypto holdings to fiat currency for users. “They have 346 million users and they’re connected to 26 million merchants,” says Spencer Montgomery, founder of Uinta Crypto Consulting. “It’s huge.”

Go tests from cn


Telegram Go tests
FROM USA